package com.xbongbong.saas.model.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.redis.PaasRedisHelper;
import com.xbongbong.paas.redis.RedisConstant;
import com.xbongbong.paas.redis.RedisPrefixConstant;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.pro.dictionary.pojo.DictionaryPojo;
import com.xbongbong.pro.dictionary.pojo.dto.DictionaryListDTO;
import com.xbongbong.pro.dictionary.pojo.vo.DictionaryVO;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.domain.dao.FormDataDictionaryDao;
import com.xbongbong.saas.domain.entity.DataDictionaryEntity;
import com.xbongbong.saas.domain.entity.FormDataDictionaryEntity;
import com.xbongbong.saas.enums.dictionary.ContractStatusEnum;
import com.xbongbong.saas.enums.dictionary.CustomerTypeEnum;
import com.xbongbong.saas.enums.dictionary.DictionaryEnum;
import com.xbongbong.saas.enums.dictionary.DictionaryTermEnum;
import com.xbongbong.saas.model.DataDictionaryModel;
import com.xbongbong.saas.model.FormDataDictionaryModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author haibin.zhang
 * @version v1.0
 * @date 2019/1/31 9:04
 * @since v1.0
 */
@Service("formDataDictionaryModel")
public class FormDataDictionaryModelImpl implements FormDataDictionaryModel {
    @Resource
    private FormDataDictionaryDao formDataDictionaryDao;
    @Resource
    private DataDictionaryModel dataDictionaryModel;
    @Resource
    private PaasRedisHelper paasRedisHelper;

    private static final Logger LOG = LoggerFactory.getLogger(FormDataDictionaryModelImpl.class);

    @Override
    public FormDataDictionaryEntity getByType(Integer type, String corpid, Long formId) {
        return formDataDictionaryDao.getByType(type,corpid,formId);
    }

    @Override
    public Integer update(Long id, String corpid, String data,Long formId) {
        return formDataDictionaryDao.update(id,corpid,data,formId);
    }

    @Override
    public FormDataDictionaryEntity getDefaultByType(Integer type) {
        return formDataDictionaryDao.getDefaultByType(type);
    }

    @Override
    public Integer insert(FormDataDictionaryEntity entity) throws XbbException {
        return formDataDictionaryDao.insert(entity);
    }

    @Override
    public Integer update(FormDataDictionaryEntity entity) throws XbbException {
        return null;
    }

    @Override
    public List<FormDataDictionaryEntity> findEntitys(Map<String, Object> param) {
        return formDataDictionaryDao.findEntitys(param);
    }

    @Override
    public void updateBatchText(List<FormDataDictionaryEntity> formDataDictionaryEntityList, String corpid) {
        formDataDictionaryDao.updateBatchText(formDataDictionaryEntityList, corpid);
    }

    @Override
    public Integer getEntitysCount(Map<String, Object> param) {
        return null;
    }

    @Override
    public List findEntitysWithoutSub(Map<String, Object> param) {
        return null;
    }

    @Override
    public FormDataDictionaryEntity getByKey(Long id, String corpid) {
        return formDataDictionaryDao.getByKey(id,corpid);
    }

    //------------以下方法从FormDataDictionaryServiceImpl内移入，后续多个项目公用的数据字典方法都降到model层

    @Override
    public DictionaryVO list(DictionaryListDTO dictionaryListDTO) throws XbbException {
        Long formId = dictionaryListDTO.getFormId();
        if (formId == null || formId == 0) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100002, SystemErrorCodeEnum.API_ERROR_100002.getMsg());
        }

        Integer type = dictionaryListDTO.getType();

        FormDataDictionaryEntity formDataDictionaryEntity = null;
        formDataDictionaryEntity = getByType(type, dictionaryListDTO.getCorpid(), formId);

        DataDictionaryEntity dataDictionaryEntity = null;
        dataDictionaryEntity = dataDictionaryModel.getByType(type, dictionaryListDTO.getCorpid());

        DictionaryEnum dictionaryEnum = DictionaryEnum.getEnumByCode(type);
        DictionaryTermEnum dictionaryTermEnum = dictionaryEnum.getDictionaryTermEnum();

        DictionaryVO dictionaryVO = new DictionaryVO();
        List<DictionaryPojo> list = new ArrayList<>();
        if (dictionaryTermEnum == DictionaryTermEnum.DATA_DICTIONARY_TERM) {
            try {
                if (dataDictionaryEntity != null) {
                    list = JSONArray.parseArray(dataDictionaryEntity.getData(),DictionaryPojo.class);
                } else {
                    list = new ArrayList<>();
                }
            }catch (Exception e){
                list = new ArrayList<>();
            }
        } else if (dictionaryTermEnum == DictionaryTermEnum.FORM_DATA_DICTIONARY_TERM) {
            try {
                if (formDataDictionaryEntity != null) {
                    list = JSONArray.parseArray(formDataDictionaryEntity.getData(),DictionaryPojo.class);
                } else {
                    list = new ArrayList<>();
                }
            }catch (Exception e){
                LOG.error("formDatadictionaryList error:corpid:" + dictionaryListDTO.getCorpid(),JSONObject.toJSONString(formDataDictionaryEntity));
                list = new ArrayList<>();
            }
        }

        if (list.isEmpty()){
            Integer initNot = dictionaryListDTO.getInitNot();
            if (dictionaryTermEnum == DictionaryTermEnum.DATA_DICTIONARY_TERM) {
                dataDictionaryEntity = dataDictionaryModel.getDefaultByType(dictionaryListDTO.getType());
                dataDictionaryEntity.setId(null);
                dataDictionaryEntity.setCorpid(dictionaryListDTO.getCorpid());
                if (initNot == null || initNot == 0) {
                    dataDictionaryModel.insert(dataDictionaryEntity);
                }
                list = JSONArray.parseArray(dataDictionaryEntity.getData(),DictionaryPojo.class);
            } else if (dictionaryTermEnum == DictionaryTermEnum.FORM_DATA_DICTIONARY_TERM) {
                //初始化
                formDataDictionaryEntity = getDefaultByType(dictionaryListDTO.getType());
                formDataDictionaryEntity.setId(null);
                formDataDictionaryEntity.setFormId(dictionaryListDTO.getFormId());
                formDataDictionaryEntity.setCorpid(dictionaryListDTO.getCorpid());
                formDataDictionaryEntity.setAddTime(DateTimeUtil.getInt());
                formDataDictionaryEntity.setUpdateTime(DateTimeUtil.getInt());
                if (initNot == null || initNot == 0) {
                    insert(formDataDictionaryEntity);
                }
                list = JSONArray.parseArray(formDataDictionaryEntity.getData(),DictionaryPojo.class);
            }
        }

        if (dictionaryTermEnum == DictionaryTermEnum.DATA_DICTIONARY_TERM) {
            dictionaryVO.setId(dataDictionaryEntity != null ? dataDictionaryEntity.getId() : null);
        } else if (dictionaryTermEnum == DictionaryTermEnum.FORM_DATA_DICTIONARY_TERM) {
            dictionaryVO.setId(formDataDictionaryEntity != null ? formDataDictionaryEntity.getId() : null);
        }
        handleList(dictionaryListDTO.getType(), list);
        dictionaryVO.setType(dictionaryListDTO.getType());
        dictionaryVO.setList(list);
        return dictionaryVO;
    }

    @Override
    public void updateBatch(String corpid, Map<Long, String> updateMap) {
        formDataDictionaryDao.updateBatch(corpid,updateMap);
    }

    @Override
    public void removeRedis(String corpid, Long formId, DictionaryEnum dictionaryEnum) {

        String filePrefix = RedisPrefixConstant.SAAS_FORM_DICTIONARY;
        if (dictionaryEnum.getDictionaryTermEnum() == DictionaryTermEnum.DATA_DICTIONARY_TERM) {
            filePrefix = RedisPrefixConstant.SAAS_DICTIONARY;
        }
        Integer type = dictionaryEnum.getType();

        Integer enable = BasicConstant.ONE;
        Integer notEnabled = BasicConstant.ZERO;

        String redisKey = String.format(RedisConstant.DICTIONARY_MAP_FORMID_NULL, corpid, type, notEnabled);
        paasRedisHelper.removeValue(filePrefix,redisKey);
        redisKey = String.format(RedisConstant.DICTIONARY_MAP_FORMID_NULL, corpid, type, enable);
        paasRedisHelper.removeValue(filePrefix,redisKey);
        redisKey = String.format(RedisConstant.DICTIONARY_MAP_FORMID_NOT_NULL, corpid, formId, type, notEnabled);
        paasRedisHelper.removeValue(filePrefix,redisKey);
        redisKey = String.format(RedisConstant.DICTIONARY_MAP_FORMID_NOT_NULL, corpid, formId, type, enable);
        paasRedisHelper.removeValue(filePrefix,redisKey);
    }

    @Override
    public void insertBatch(List<FormDataDictionaryEntity> list) {
        formDataDictionaryDao.insertBatch(list);
    }

    /**
     * 特殊处理数据字典项
     *
     * @param type
     * @param list
     * @throws
     * @author long.rao
     * @date 2019-08-27 15:38
     */
    private void handleList(Integer type, List<DictionaryPojo> list) {
        if (list.isEmpty()) {
            return;
        }
        DictionaryEnum dictionaryEnum = DictionaryEnum.getEnumByCode(type);
        switch (dictionaryEnum) {
            case CUSTOMER_STATUS:
                list.forEach(item -> {
                    if (Objects.equals(item.getValue(), CustomerTypeEnum.TRANSACTION_CUSTOMER.getCode()) ||
                            Objects.equals(item.getValue(), CustomerTypeEnum.LOYAL_CUSTOMERS.getCode()) ||
                            Objects.equals(item.getValue(), CustomerTypeEnum.INVALID_CUSTOMER.getCode())) {
                        item.setDisableEnable(BasicConstant.ONE);
                        item.setDisableDel(BasicConstant.ONE);
                        item.setDisableName(BasicConstant.ZERO);
                        item.setSourceName(CustomerTypeEnum.getByCode(item.getValue()).getName());
                    }
                });
                break;
            case CONTRACT_STATUS:
                list.forEach(item -> {
                    if (Objects.equals(item.getValue(), ContractStatusEnum.TERMINATION.getCode())) {
                        item.setDisableEnable(BasicConstant.ONE);
                        item.setDisableDel(BasicConstant.ONE);
                        item.setDisableName(BasicConstant.ZERO);
                        item.setSourceName(ContractStatusEnum.getByCode(item.getValue()).getName());
                    }
                });
                break;
            case SALE_STAGE_WASTAGE:
                list.forEach(item -> {
                    List<String> requiredAttrList = item.getRequiredAttrList();
                    List<String> showAttrList = item.getShowAttrList();
                    if(CollectionsUtil.isNotEmpty(requiredAttrList) &&
                            (showAttrList==null || showAttrList.size()<requiredAttrList.size())){
                        showAttrList = new ArrayList<>();
                        showAttrList.addAll(requiredAttrList);
                        item.setShowAttrList(showAttrList);
                    }
                });
                break;
            default:
                break;
        }
    }
}
